package cn.net.sinodata.system.msghandler.process;

import cn.hutool.core.collection.CollectionUtil;
import cn.net.sinodata.common.core.enums.MsgParseHandlerTypeEnum;
import cn.net.sinodata.common.core.enums.TaskTypeEnum;
import cn.net.sinodata.system.domain.*;
import cn.net.sinodata.system.domain.vo.BmTransSerialVo;
import cn.net.sinodata.system.msghandler.exception.MsgParseException;
import cn.net.sinodata.system.msghandler.process.base.BaseMsgProcessHandler;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Element;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 中债流程处理类
 */
@Slf4j
public class CCDCMsgProcessHandler extends BaseMsgProcessHandler {

    public CCDCMsgProcessHandler(BmTransLogRecord bmTransLogRecord, BmTransLogMsg bmTransLogMsg, MsgParseHandlerTypeEnum handlerType) {
        super(bmTransLogRecord, bmTransLogMsg, handlerType);
    }

    @Override
    public Map<String, Object> getCommonInfo(BmTransLogRecord bmTransLogRecord, BmTransLogMsg bmTransLogMsg) throws Exception {
        log.info("中债心获取公共信息-开始");
        HashMap<String, Object> commonInfoMap = new HashMap<>();
        String respMsg = bmTransLogMsg.getResponseMsg();
        Element element;
        try {
            element = msgParseHandler.parse(respMsg);
        } catch (Exception e) {
            log.error("报文解析失败:", e);
            throw new MsgParseException("报文解析失败:" + e.getMessage());
        }

        // 获取报文格式
        Element msgDefIdrElement = (Element)element.selectSingleNode("/Root/AppHdr/MsgDefIdr");
        if (msgDefIdrElement != null && msgDefIdrElement.hasContent()) {
            String msgDefIdr = msgDefIdrElement.getText();
            commonInfoMap.put("MsgDefIdr", msgDefIdr);
        } else {
            log.warn(bmTransLogRecord.getTransSerial() + "报文没有MsgDefIdr，无法确认报文类型");
        }

        // 获取成交编号
        Element acctOwnrTxIdElement = null;
        if ("ccdc.104.001.01".equals(commonInfoMap.get("MsgDefIdr"))) {
            acctOwnrTxIdElement = (Element)element.selectSingleNode("/Root/Document/SctiesSttlmTxStsAdvc/TxId/AcctOwnrTxId");
        } else if ("ccdc.107.001.01".equals(commonInfoMap.get("MsgDefIdr"))) {
            acctOwnrTxIdElement = (Element)element.selectSingleNode("/Root/Document/SctiesFincgStsAdvc/TxId/AcctOwnrTxId");
        } else if ("ccdc.105.001.01".equals(commonInfoMap.get("MsgDefIdr"))) {
            acctOwnrTxIdElement = (Element)element.selectSingleNode("/Root/Document/SctiesSttlmTxConf/TxIdDtls/AcctOwnrTxId");
        } else if("ccdc.108.001.01".equals(commonInfoMap.get("MsgDefIdr"))) {
            acctOwnrTxIdElement = (Element)element.selectSingleNode("/Root/Document/SctiesFincgConf/TxIdDtls/AcctOwnrTxId");
        }
        if (acctOwnrTxIdElement != null && acctOwnrTxIdElement.hasContent()) {
            String acctOwnrTxId = acctOwnrTxIdElement.getText();
            commonInfoMap.put("AcctOwnrTxId", acctOwnrTxId);
        } else {
            log.warn(bmTransLogRecord.getTransSerial() + "报文没有AcctOwnrTxId，报文缺失");
        }

        log.info("中债获取公共信息-结束");
        return commonInfoMap;
    }

    @Override
    public TaskTypeEnum taskTypeHandle(BmTransLogRecord bmTransLogRecord, BmTransLogMsg bmTransLogMsg) throws Exception {
        log.info("中债判断报文类型-开始");
        String msgDefIdr = (String)commonInfo.get("MsgDefIdr");
        log.info("中债任务类型为:{}", msgDefIdr);
        TaskTypeEnum taskTypeEnum = null;
        // TODO 需更新成枚举值
        if ("ccdc.104.001.01".equals(msgDefIdr) || "ccdc.107.001.01".equals(msgDefIdr)) { // 交易确认
            taskTypeEnum = TaskTypeEnum.CONFIRM;
        } else if ("ccdc.105.001.01".equals(msgDefIdr) || "ccdc.108.001.01".equals(msgDefIdr)) { // 交易清算
            taskTypeEnum = TaskTypeEnum.CLEARING;
        }
        log.info("中债判断报文类型-结束");
        return taskTypeEnum;
    }

    @Override
    public PmMonitorProduct getMonitorProduct(BmTransLogRecord bmTransLogRecord, BmTransLogMsg bmTransLogMsg) throws Exception {
        log.info("获取监控产品信息-开始");
        String acctOwnrTxId = (String) commonInfo.get("AcctOwnrTxId");
        // TODO 根据成交编号应该只能查询出来一条还是可能存在多条，如果存在多条，如果确认匹配的是哪一笔
        List<BmTransSerial> transSerials = bmTransSerialMapper.selectList(new QueryWrapper<BmTransSerial>().eq("trans_serial", acctOwnrTxId));
        if (CollectionUtil.isEmpty(transSerials)) {
            // TODO 流水号查不到怎么处理，作为异常录入
            log.warn("查询流水表，未获取到对应的流水记录");
            return null;
        }

        PmMonitorProduct pmMonitorProduct;
        if (transSerials.size() == 1) {
            BmTransSerial bmTransSerial = transSerials.get(0);
            String bizType = bmTransSerial.getBizType();
            pmMonitorProduct = pmMonitorProductMapper.selectOne(new QueryWrapper<PmMonitorProduct>().eq("biz_type", bizType));
        } else {
            // TODO 多条的情况如何处理
            pmMonitorProduct = null;
        }

        log.info("获取监控产品信息-结束");
        return pmMonitorProduct;
    }

    @Override
    public void trans(BmTransSerial bmTransSerial, BmTransSubSerial bmTransSubSerial) throws Exception {
        throw new Exception("中债不支持成交业务");
    }

    @Override
    public void confirm(BmTransSerial bmTransSerial, BmTransSubSerial bmTransSubSerial) throws Exception {
        // TODO
    }

    @Override
    public void clearing(BmTransSerial bmTransSerial, BmTransSubSerial bmTransSubSerial) throws Exception {
        // TODO
    }
}
